package com.utils;

import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import com.show.api.util.StringUtils;

import java.io.*;

import sun.misc.*;

import java.security.MessageDigest;
import java.net.URL;
import java.net.URLConnection;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Util {
    /**
     * 完整时间 yyyy-MM-dd HH:mm:ss
     */
    public static final String simple = "yyyy.MM.dd HH:mm:ss";

    public static class HttpResp {
        public int ret_code;
        public double cust_val;
        public String err_msg;
        public String req_id;
        public String rsp_data;
        public String pred_resl;
    }

    // 为避免引入复杂的json包，这里简单实现一个，只用来能解析从网络的回包中的指定字段的内容
    public static class JsonHelper {
        public String json;
        public int next_idx;

        public JsonHelper(String json) {
            this.json = json;
            this.next_idx = 0;
        }

        public void Skip() {
            while (next_idx < json.length()) {
                char c = json.charAt(next_idx);
                if ((c <= 32) || (c == '\\')) {
                    next_idx++;
                } else
                    break;
            }
        }

        public String NextSToken() {
            //int start = next_idx;
            String ret = "";
            while (next_idx < json.length()) {
                char c = json.charAt(next_idx);
                if (c == '\"')
                    break;
                if ((c == '\\') && (next_idx + 1 < json.length())) {
                    if (json.charAt(next_idx + 1) == '\\') {
                        ret += '\\';
                        next_idx += 2;
                        continue;
                    }
                    if (json.charAt(next_idx + 1) == '\"') {
                        ret += '\"';
                        next_idx += 2;
                        continue;
                    }
                }
                ret += c;
                next_idx++;
            }
            return ret;
        }

        public String NextNToken() {
            String ret = "";
            while (next_idx < json.length()) {
                char c = json.charAt(next_idx);
                if (c == '\\') {
                    next_idx++;
                    continue;
                }
                if ((c < '0' || c > '9') && c != '.') {
                    // not number
                    break;
                }
                ret += c;
                next_idx++;
            }
            return ret;
        }

        public void Key2Val(HttpResp rsp, String key, String val) {
            if (key.equals("RetCode")) {
                rsp.ret_code = Integer.parseInt(val);
            } else if (key.equals("ErrMsg")) {
                rsp.err_msg = val;
            } else if (key.equals("RequestId")) {
                rsp.req_id = val;
            } else if (key.equals("RspData")) {
                rsp.rsp_data = val;
            } else if (key.equals("result")) {
                rsp.pred_resl = val;
            } else if (key.equals("cust_val")) {
                rsp.cust_val = Double.parseDouble(val);
            }
        }

        public void Parse(HttpResp rsp) {
            //rsp.ret_code    = -1;
            next_idx = 0;
            String key = "";
            String sval = "";
            for (next_idx = 0; next_idx < json.length(); ) {
                Skip();
                char c = json.charAt(next_idx);
                switch (c) {
                    case ':':
                    case ',':
                        break;
                    case '[':
                    case '{':
                    case '}':
                    case ']':
                        // not support here
                        break;
                    case '\"':
                        next_idx++;
                        sval = NextSToken();
                        Skip();
                        if (next_idx >= json.length())
                            break;
                        if (json.charAt(next_idx + 1) == ':') {
                            key = sval;
                            next_idx++;
                            continue;
                        }
                        // key to val
                        Key2Val(rsp, key, sval);
                        key = "";
                        break;
                    case '+':
                    case '-':
                    case '.':
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9':
                        // is number
                        sval = NextNToken();
                        // key to val
                        Key2Val(rsp, key, sval);
                        key = "";
                        break;
                    case 'n':
                    case 'N':
                        sval = json.substring(next_idx, 4).toLowerCase();
                        if (!sval.equals("null")) {
                            //error
                            break;
                        }
                        sval = "";
                        next_idx += 4;
                        // key to val
                        Key2Val(rsp, key, sval);
                        key = "";
                        break;
                    default:
                        break;
                }
                next_idx++;
            }
        }
    }

    public static String ToHex(byte[] arr) {
        StringBuffer md5str = new StringBuffer();
        int digital;
        for (int i = 0; i < arr.length; i++) {
            digital = arr[i];
            if (digital < 0) {
                digital += 256;
            }
            if (digital < 16) {
                md5str.append("0");
            }
            md5str.append(Integer.toHexString(digital));
        }
        return md5str.toString().toLowerCase();
    }

    public static String CalcMd5(String src) {
        String md5str = "";
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] input = src.getBytes();
            byte[] buff = md.digest(input);
            md5str = ToHex(buff);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return md5str;
    }

    public static String CalcBase64(byte[] data) {
        String s = "";
        if (data != null) {
            s = Base64.encodeToString(data, Base64.DEFAULT);
        }
        return s;
    }

    public static String CalcSign(String id, String key, String tm) {
        String chk1 = CalcMd5(tm + key);
        String sum = CalcMd5(id + tm + chk1);
        //System.out.printf("userid: %s key: %s tm: %s chk1: %s chk2: %s\n", id, key, tm, chk1, sum);
        return sum;
    }

    public static HttpResp ParseHttpResp(String resl) {
        HttpResp resp = new HttpResp();
        resp.ret_code = -1;
        JsonHelper json = new JsonHelper(resl);
        json.Parse(resp);
        if (!resp.rsp_data.isEmpty()) {
            JsonHelper rjson = new JsonHelper(resp.rsp_data);
            rjson.Parse(resp);
        }
        return resp;
    }

    /**
     * 判断字符串中是否包含中文
     * @param str
     * 待校验字符串
     * @return 是否为中文
     * @warn 不能校验是否为中文标点符号
     */
    public static boolean isContainChinese(String str) {
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(str);
        if (m.find()) {
            return true;
        }
        return false;
    }


    public static byte[] ReadBinaryFile(String file_name) throws IOException {
        InputStream in = null;
        BufferedInputStream buffer = null;
        DataInputStream dataIn = null;
        ByteArrayOutputStream bos = null;
        DataOutputStream dos = null;
        byte[] bArray = null;
        try {
            in = new FileInputStream(file_name);
            buffer = new BufferedInputStream(in);
            dataIn = new DataInputStream(buffer);
            bos = new ByteArrayOutputStream();
            dos = new DataOutputStream(bos);
            byte[] buf = new byte[1024];
            while (true) {
                int len = dataIn.read(buf);
                if (len < 0)
                    break;
                dos.write(buf, 0, len);
            }
            bArray = bos.toByteArray();
        } catch (Exception e) {
            return bArray;
        } finally {
            if (in != null)
                in.close();
            if (dataIn != null)
                dataIn.close();
            if (buffer != null)
                buffer.close();
            if (bos != null)
                bos.close();
            if (dos != null)
                dos.close();
        }
        return bArray;
    }

    public static String HttpPost(String url, String params) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(params);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }


    public static String md5(String string) {
        if (TextUtils.isEmpty(string)) {
            return "";
        }
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest(string.getBytes());
            StringBuilder result = new StringBuilder();
            for (byte b : bytes) {
                String temp = Integer.toHexString(b & 0xff);
                if (temp.length() == 1) {
                    temp = "0" + temp;
                }
                result.append(temp);
            }
            return result.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 获取标准中国时区日期
     *
     * @return
     */
    public static String getStandardDate(String split) {
        SimpleDateFormat dff = new SimpleDateFormat("yyyy" + split + "MM" + split + "dd");
        dff.setTimeZone(TimeZone.getTimeZone("GMT+08"));
        String ee = dff.format(new Date());
        return ee;
    }

    /**
     * 判断指定时间是否在当前时间退后几天内
     *
     * @param dayNum---"3"       指定日期
     * @param date---"2019.7.30" 退后天数，1为当天
     * @return
     */
    public static boolean isInquireDate(String dayNum, String date) {
        boolean inquire = false;
        long time1 = getFormerlyStandardDate(dayNum);
        long time2 = 0;
        Date timestamp1 = strToDate(date + " 0:0:0", simple);
        if (timestamp1 != null) {
            time2 = timestamp1.getTime();
        }
        System.out.println("银行" + time2);
        if (time1 <= time2) {
            inquire = true;
        } else {
            inquire = false;
        }
        return inquire;
    }

    /**
     * 获取指定月份的最后一天
     *
     * @param yearMonth 指定年月  2019.05
     * @return 最后一天
     */
    public static String getLastDayOfMonth(String yearMonth) {
        String[] strings = yearMonth.split("\\.");
        int year = Integer.parseInt(strings[0]);  //年
        int month = Integer.parseInt(strings[1]); //月
        Calendar cal = Calendar.getInstance();
        // 设置年份
        cal.set(Calendar.YEAR, year);
        // 设置月份
        cal.set(Calendar.MONTH, month - 1);
        // 获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DATE);
        // 设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        // 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
        return sdf.format(cal.getTime());
    }

    /**
     * 获取过去几天的日期时间戳
     *
     * @return
     */
    public static long getFormerlyStandardDate(String dayNum) {
        SimpleDateFormat dff = new SimpleDateFormat("yyyy.MM.dd");
        dff.setTimeZone(TimeZone.getTimeZone("GMT+08"));
        String date = dff.format(new Date(System.currentTimeMillis() - ((Long.parseLong(dayNum) - 1) * 24 * 3600 * 1000)));
        Date date1 = strToDate(date + " 00:00:00", simple);
        if (date1 != null) {
            return date1.getTime();
        }
        return 0;
    }

    /**
     * 反向格式化日期
     *
     * @param str       要格式化字符串
     * @param formatStr 字符串的日期格式
     * @return
     */
    public static Date strToDate(String str, String formatStr) {
        try {
            if (str == null)
                return null;
            if (formatStr == null) {
                formatStr = "yyyy.MM.dd hh:mm";
            }
            SimpleDateFormat defaultDate = new SimpleDateFormat(formatStr);
            Date date = null;
            date = defaultDate.parse(str);
            return date;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取精确到秒的时间戳
     *
     * @param date
     * @return
     */
    public static int getTimestamp(Date date) {
        if (null == date) {
            return 0;
        }
        String timestamp = String.valueOf(date.getTime() / 1000);
        return Integer.valueOf(timestamp);
    }

    /**
     * 获取精确到秒的时间差是否大于6小时
     *
     * @param date 之前的时间
     * @return
     */
    public static boolean isTimeOut(String date) {
        if (StringUtils.isEmpty(date)) {
            return true;
        }
        //上次时间戳
        long oldTime = Long.parseLong(date) / 1000;
        long newTime = System.currentTimeMillis() / 1000;
        boolean timeOut = newTime - oldTime >= 60 * 60 * 6;
        return timeOut;
    }

    /**
     * 判定当前日期是否与缓存日期非同一天
     *
     * @param date 之前的时间
     * @return
     */
    public static boolean outpaceZero(String date) {
        if (StringUtils.isEmpty(date)) {
            return true;
        }
        long l = Long.parseLong(date);
        //        SimpleDateFormat time=new SimpleDateFormat("yyyy年MM-dd HH mm ss");
        SimpleDateFormat time = new SimpleDateFormat("dd");
        String oldDay = time.format(l);
        String newDay = time.format(System.currentTimeMillis());
        Log.i("oldDay", oldDay);
        Log.i("newDay", newDay);
        if (!oldDay.equals(newDay)) {
            return true;
        }
        return false;
    }

    /**
     * 得到可用金额
     *
     * @param str
     * @return
     */
    public static String replaceMoney(String str) {
        String money = "";
        String regxp = "((-)?(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){1,2})?)";
        str = str.replaceAll(",", "");
        Pattern p = Pattern.compile(regxp);
        Matcher m = p.matcher(str);
        while (m.find()) {
            money = m.group();
        }
        return StringUtils.isEmpty(money) ? "0.00" : money;
    }
}
